﻿using MudBlazor.Utilities;

namespace MXERP.Blazor.Components
{
    public partial class Tabs : MudComponentBase
    {
        protected string TabsClassName =>
        new CssBuilder("md-tabs")
                .AddClass(Class)
                .Build();
        protected string TabBarClassName =>
            new CssBuilder("md-tabs-tabbar")
            .AddClass($"mud-elevation-{Elevation}")
            .Build();

        protected string PanelsClassName =>
            new CssBuilder("md-tabs-panels")
            .AddClass(TabPanelClass)
            .Build();
        private bool _isRendered = false;
        private List<TabPanel> _tabPanels;
        public IReadOnlyList<TabPanel> TabPanels { get; private set; }
        private TabPanel _activePane;

        private string _activeKey;
        [Parameter]
        public string ActiveKey
        {
            get => _activeKey;
            set
            {
                if (_activeKey != value)
                {
                    _activeKey = value;
                    ActivatePane(_activeKey);
                }
            }
        }
        [Parameter]
        public string DefaultActiveKey { get; set; }

        [Parameter]
        public int Elevation { set; get; } = 1;
        [Parameter]
        public RenderFragment ChildContent { get; set; }

        /// <summary>
        /// Custom class/classes for TabPanel
        /// </summary>
        [Parameter]
        public string TabPanelClass { get; set; }
        [Parameter]
        public bool KeepPanelsAlive { get; set; } = false;
        /// <summary>
        /// The callback, when the close button has been clicked
        /// </summary>
        [Parameter] public EventCallback<TabPanel> CloseTab { get; set; }

        [Parameter]
        public EventCallback<string> ActiveKeyChanged { get; set; }

        [Parameter]
        public EventCallback<string> OnChange { get; set; }

        public Tabs()
        {
            _tabPanels = new List<TabPanel>();
            TabPanels = _tabPanels.AsReadOnly();
        }
        
        internal void AddTabPanel(TabPanel tabPanel)
        {
            _tabPanels.Add(tabPanel);
            Complete();
        }

        internal void Complete()
        {
            if (!string.IsNullOrWhiteSpace(ActiveKey))
            {
                var activedPanel = _tabPanels.Find(x => x.Key == ActiveKey);
                if (activedPanel?.IsActive == false)
                {
                    ActivatePane(activedPanel.Key);
                }
            }
            else if (!string.IsNullOrWhiteSpace(DefaultActiveKey))
            {
                var defaultPanel = _tabPanels.FirstOrDefault(x => x.Key == DefaultActiveKey);
                if (defaultPanel != null)
                {
                    ActivatePane(defaultPanel.Key);
                }
            }

            //if (_activePane == null || _tabPanels.All(x => !x.IsActive))
            //{
            //    ActivatePane(_tabPanels.FirstOrDefault()?.Key);
            //}
        }

        private void ActivatePane(string key)
        {
            if (_tabPanels.Count == 0)
                return;
            var tabPanel = _tabPanels.Find(p => p.Key == key);

            if (tabPanel == null)
                return;
            _activePane?.SetActive(false);

            tabPanel.SetActive(true);

            _activePane = tabPanel;

            if (_activeKey != _activePane.Key)
            {
                if (ActiveKeyChanged.HasDelegate)
                {
                    ActiveKeyChanged.InvokeAsync(_activePane.Key);
                }
                _activeKey = _activePane.Key;
            }


            //Card?.SetBody(_activePane.ChildContent);

            //_needUpdateScrollListPosition = true;

            //_shouldRender = true;
            InvokeAsync(StateHasChanged);
        }
        
        internal async Task RemoveTabPanel(TabPanel tabPanel)
        {
            var index = _tabPanels.IndexOf(tabPanel);
            if (tabPanel.IsActive && _tabPanels.Count > 0)
            {
                var p = index > 1 ? _tabPanels[index - 1] : _tabPanels[0];
                ActivatePane(p.Key);
            }
            if (CloseTab.HasDelegate)
            {
                await CloseTab.InvokeAsync(tabPanel);
            }
            _tabPanels.Remove(tabPanel);
        }

        string GetTabClass(TabPanel panel)
        {
            var tabClass = new CssBuilder("md-tab")
              .AddClass($"md-tab-active", when: () => panel == _activePane)
              .AddClass(panel.Class)
              .Build();

            return tabClass;
        }

        //[Inject]
        //IJSRuntime JS { get; set; }
        //[Inject]
        //public TabSetTool TabSetTool { get; set; }
        //[Inject]
        //public ILocalStorageService LocalStorage { get; set; }

        //[CascadingParameter(Name = "RouteView")]
        //public ReuseTabsRouteView RouteView { get; set; }
        //public List<Tab> Tabs => TabSetTool.Pages;

        //private int OffsetLeft { get; set; }

        //private async Task MoveLeft()
        //{
        //    var tabsWidth = await JS.InvokeAsync<int>("GetWidth", ".middletab");
        //    MoveTo(OffsetLeft - tabsWidth);
        //}
        //private async Task MoveRight()
        //{
        //    var tabsWidth = await JS.InvokeAsync<int>("GetWidth", ".middletab");

        //    var moveS = OffsetLeft + tabsWidth;
        //    var temp = 0;
        //    Tab soTab = null;
        //    foreach (var tab in Tabs)
        //    {
        //        temp += tab.TabWidth;
        //        if (temp > moveS)
        //        {
        //            soTab = tab;
        //            break;
        //        }
        //    }
        //    if (soTab == null)
        //    {
        //        soTab = Tabs.LastOrDefault();
        //    }
        //    if (soTab != null)
        //    {
        //        await ScrollToTab(soTab);
        //    }

        //}
        //private async Task CloseTab(Tab tab)
        //{
        //    var index = Tabs.IndexOf(tab);
        //    Tabs.Remove(tab);

        //    if (tab.IsActive)
        //    {
        //        Tab activeTab = null;
        //        if (index > 0)
        //        {
        //            activeTab = Tabs[index - 1];
        //        }
        //        else if (Tabs.Count > 0)
        //        {
        //            activeTab = Tabs[0];
        //        }
        //        if (activeTab != null)
        //        {
        //            await ActivateTab(activeTab);
        //        }
        //    }
        //    if (tab.OnClose != null)
        //    {
        //        await tab.OnClose();
        //    }
        //}
        //private async Task CloseOther()
        //{

        //    Tabs.RemoveAll(m => !m.IsActive);
        //    if (Tabs.Count > 0)
        //    {
        //        await ScrollToTab(Tabs.FirstOrDefault());
        //    }
        //}

        //protected override async Task OnAfterRenderAsync(bool firstRender)
        //{
        //    if (Tabs == null)
        //    {
        //        return;
        //    }
        //    var hasAdd = false;
        //    for (var i = 0; i < Tabs.Count; i++)
        //    {
        //        var item = Tabs[i];
        //        if (item.IsActive)
        //        {
        //            if (string.IsNullOrEmpty(item.Title))
        //            {
        //                item.Title = await LocalStorage.GetItemAsStringAsync("Title-" + item.Url);
        //            }
        //            else
        //            {
        //                await LocalStorage.SetItemAsStringAsync("Title-" + item.Url, item.Title);
        //            }
        //        }
        //        if (item.TabWidth <= 0)
        //        {
        //            hasAdd = true;
        //            item.TabWidth = await JS.InvokeAsync<int>("GetTabWidth", i);
        //        }
        //    }
        //    if (hasAdd)
        //    {
        //        await ScrollToTab(Tabs.FirstOrDefault(m => m.IsActive));
        //        StateHasChanged();
        //    }
        //}

        //public async Task ScrollToTab(Tab tab)
        //{
        //    var top = Tabs.IndexOf(tab);
        //    var offset = Tabs.Take(top).Sum(m => m.TabWidth);
        //    var other = Tabs.Skip(top).Sum(m => m.TabWidth == 0 ? GetLength(m.Title) * 8 + 20 : m.TabWidth);

        //    var tabsWidth = await JS.InvokeAsync<int>("GetWidth", ".middletab");
        //    if (offset + other < tabsWidth - 100)
        //    {
        //        OffsetLeft = 0;
        //        return;
        //    }
        //    if (other < tabsWidth - 100)
        //    {
        //        MoveTo(offset + other - tabsWidth + 100);
        //        return;
        //    }
        //    OffsetLeft = offset;
        //}
        //public static int GetLength(string str)
        //{

        //    if (str.Length == 0) return 0;

        //    ASCIIEncoding ascii = new ASCIIEncoding();
        //    int tempLen = 0;
        //    byte[] s = ascii.GetBytes(str);
        //    for (int i = 0; i < s.Length; i++)
        //    {
        //        if (s[i] == 63)
        //        {
        //            tempLen += 2;
        //        }
        //        else
        //        {
        //            tempLen += 1;
        //        }
        //    }

        //    return tempLen;
        //}
        //private void MoveTo(int x)
        //{
        //    if (x <= 0)
        //    {
        //        OffsetLeft = 0;
        //        return;
        //    }
        //    var temp = 0;
        //    bool isSet = false;
        //    foreach (var item in Tabs)
        //    {
        //        if (temp + item.TabWidth > x)
        //        {
        //            isSet = true;
        //            temp += item.TabWidth;
        //            break;
        //        }
        //        temp += item.TabWidth;
        //    }
        //    if (isSet)
        //    {
        //        OffsetLeft = temp;
        //    }
        //    else
        //    {
        //        OffsetLeft = x;
        //    }
        //}
    }
}
